package com.tbit.uqbike.client.service.impl;

import com.tbit.uqbike.client.constant.AccountConfigExtConstant;
import com.tbit.uqbike.client.dao.core.AccountConfigExtDao;
import com.tbit.uqbike.client.dao.core.ProhibitAreaDao;
import com.tbit.uqbike.client.pojo.Point;
import com.tbit.uqbike.client.pojo.ProhibitArea;
import com.tbit.uqbike.client.pojo.newEntity.AccountConfigExt;
import com.tbit.uqbike.client.service.ProhibitAreaService;
import com.tbit.uqbike.client.service.prohibitarea.CheckProhibitAreaResult;
import com.tbit.uqbike.client.util.GeoUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * @Author: chen
 * @Description: 禁停区
 * @Date: 创建于 10:50 2020/4/9
 */
@Service
@Slf4j
public class ProhibitAreaServiceImpl implements ProhibitAreaService {
    @Autowired
    private ProhibitAreaDao prohibitAreaDao;
    @Autowired
    private AccountConfigExtDao accountConfigExtDao;

    @Override
    public List<ProhibitArea> getByArea(Integer accountId, Double lo, Double la) {
        int radius = Optional.ofNullable(accountConfigExtDao.selectByAccountIdAndKey(accountId, AccountConfigExtConstant.PROHIBIT_AREA_SCOPE))
                .map(AccountConfigExt::getParamValue)
                .map(Integer::parseInt)
                .orElse(500);

        // 配置值为0表示查询整个运营区的数据
        if (radius == 0) {
            return prohibitAreaDao.getByAccountId(accountId);
        }

        return getByAreaAndRadius(accountId, lo, la, radius);
    }

    @Override
    public List<ProhibitArea> getByAreaAndRadius(Integer accountId, Double lo, Double la, Integer radius) {
        Point[] rect = GeoUtil.getBoundingBox(lo, la, radius);

        Map<String, Object> params = new HashMap<String, Object>();
        params.put("accountId", accountId);
        params.put("minLo", rect[0].getX());
        params.put("minLa", rect[0].getY());
        params.put("maxLo", rect[1].getX());
        params.put("maxLa", rect[1].getY());
        return prohibitAreaDao.getByArea(params);
    }


    /**
     * 检查是否在禁停区域内
     * 当在禁停区域内时返回禁停区域id
     *
     * @param accountId 区域id
     * @param point     待检查点
     */
    @Override
    public CheckProhibitAreaResult checkInProhibitArea(Integer accountId, Point point) {
        List<ProhibitArea> prohibitAreas = getByAreaAndRadius(accountId, point.getX(), point.getY(), 10000);

        CheckProhibitAreaResult result = CheckProhibitAreaResult.fail(point,null);
        for (ProhibitArea prohibitArea : prohibitAreas) {
            result = prohibitArea.checkInProhibitArea(point);
            if (result.inProhibitArea()) {
                return result;
            }
        }
        return result;
    }
}
